﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JSON;
using System.Configuration;
using System.Security.Cryptography;

namespace Facebook_Graph_Toolkit.Helpers {
    internal static class Common {
        internal static DateTime RFC3339ToDateTime(string RFC3339) {
            DateTime date = new DateTime(Convert.ToInt32(RFC3339.Substring(0, 4)),
                Convert.ToInt32(RFC3339.Substring(5, 2)), Convert.ToInt32(RFC3339.Substring(8, 2)),
                Convert.ToInt32(RFC3339.Substring(11, 2)), Convert.ToInt32(RFC3339.Substring(14, 2)),
                Convert.ToInt32(RFC3339.Substring(17, 2)));
            return date;
        }
        internal static DateTime UnixTimestampToDateTime(double UnixTimestamp) {
            DateTime D = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return D.AddSeconds(UnixTimestamp);
        }
        internal static double ToUnixTimestamp(DateTime date) {
            DateTime D = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return (date - D).TotalSeconds;
        }
        internal static string Base64UrlDecode(string s) {
            s = s.Replace('+', '-').Replace('/', '_').Trim();
            int pad = s.Length % 4;
            if (pad > 0) {
                pad = 4 - pad;
            }
            return s.PadRight(s.Length + pad, '=');
        }
        internal static string Base64Decode(string s) {
            byte[] decbuff = Convert.FromBase64String(s);
            return Encoding.UTF8.GetString(decbuff);
        }
        internal static JsonObject ParseSignedRequest(string SignedRequest, string AppSecret) {
            string[] EncodedParts = SignedRequest.Split('.');

            string JSONString = Base64Decode(Base64UrlDecode(EncodedParts[1]));
            JsonObject data = new JsonObject(JSONString);
            if (data["algorithm"].ToString() != "HMAC-SHA256") throw new FacebookException("Unknown algorithm. Expected HMAC-SHA256.");

            HMACSHA256 Cryp = new HMACSHA256(Encoding.UTF8.GetBytes(AppSecret));
            byte[] hashbytes = Cryp.ComputeHash(Encoding.UTF8.GetBytes(EncodedParts[1]));
            string calculatedhash = Base64UrlDecode(Convert.ToBase64String(hashbytes));

            string givenhash = Base64UrlDecode(EncodedParts[0]);

            Cryp.Clear();

            if (givenhash != calculatedhash) throw new FacebookException("Invalid signature. Check your Application Secret.");

            return data;
        }
        internal static string BuildUrlQuery(string url, IDictionary<string, string> parameters) {
            bool firstvalue = true;
            foreach (KeyValuePair<string, string> kvp in parameters) {
                if (string.IsNullOrEmpty(kvp.Value)) continue;
                if (firstvalue) {
                    url += "?" + kvp.Key + "=" + kvp.Value;
                    firstvalue = false;
                } else url += "&" + kvp.Key + "=" + kvp.Value;
            }
            return url;
        }
        internal static string BuildQueryString(IDictionary<string, string> parameters) {
            string querystring = "";
            bool firstvalue = true;
            foreach (KeyValuePair<string, string> kvp in parameters) {
                if (string.IsNullOrEmpty(kvp.Value)) continue;
                if (firstvalue) {
                    querystring = kvp.Key + "=" + kvp.Value;
                    firstvalue = false;
                } else querystring += "&" + kvp.Key + "=" + kvp.Value;
            }
            return querystring;
        }
        internal static FacebookGraphToolkitConfiguration GetAppConfig(bool required) {
            FacebookGraphToolkitConfiguration Config = (FacebookGraphToolkitConfiguration)ConfigurationManager.GetSection("FacebookGraphToolkitConfiguration");
            if (Config == null && required) throw new ConfigurationErrorsException("Cannot find Facebook Application Configuration in web.config");
            return Config;
        }
    }
}
